{-# LANGUAGE RankNTypes                 #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE DeriveFunctor              #-}
{-# LANGUAGE DeriveFoldable             #-}
module OpenCog.Lojban.Syntax.Types where

import Prelude hiding (id,(.),(<*>),(<$>),(*>),(<*))

import Data.List (partition,isPrefixOf,isSuffixOf,nub,any,intercalate)
import Data.Maybe (fromJust)
import qualified Data.Map as M
import qualified Data.ListTrie.Patricia.Set.Ord as TS
import Control.Monad.RWS

import Iso
import qualified Syntax

import Lojban hiding (State(..))

import OpenCog.AtomSpace
import OpenCog.Lojban.Util

type StringSet = TS.TrieSet Char

type Tag = String
type Tagged a = (a,Maybe Tag)

--Sumtis are tagged atoms where the tag descripes their place in the predicate
type Sumti = Tagged Atom

--Selbri are Atoms with a TruthVal they can also be tagged with a strength modifier
type Selbri = (TruthVal,Atom)
type SelbriNA = (Maybe NA,Selbri)

--Strength modifier with attached UIs
type NA = (String,[UI])

--Attitudinal with Strength
type UI = (Atom,TruthVal)

--The State
--sFlags : A list of flags then can be used to pass information along
--sAtoms : A list of Atoms that will be generated by parsing
--sTVLs  : A list of TypedVariableLinks
--sText  : The actuall text to be parsed
--sSeed  : Random seed for name gerneration
--sNow   : Context of the Utterance
--sCtx   : Other contexts that are related to sNow, First one is the Context of the Sentence
--sJAI   : Keep track of Jai place
--sDA    : Function to wrap the sentence in the neccesary ForAll/Exists links
--sDaM   : Map for all DA to their current instantiation
--sXU    : List of sumti taged by xu
type Flag = String
data State = State { sFlags :: M.Map String String
                   , sAtoms :: [Atom]
                   , sTVLs  :: [Atom]
                   , sText  :: String
                   , sSeed  :: Int
                   , sNow   :: Atom
                   , sCtx   :: [Atom]
                   , sJAI   :: Maybe JJCTTS
                   , sDA    :: (Atom -> Atom)
                   , sDaM   :: M.Map String Atom
                -- , sPro   :: M.Map String String
                   , sXU    :: [Atom]
                   }

--They Iso we are using
--We use a RWST monad over (Either String) for failurs
--currently the writer part is unused
type SynIso a b = Syntax.SynIso (RWST (WordList State) () State) a b
type Syntax a   = SynIso () a

--The parser Requirse that the State is a SyntaxState
instance Syntax.SyntaxState State where
    getText = sText
    addText str sta = sta {sText = str ++ sText sta}
    setText str sta = sta {sText = str}

-------------------------------------------------------------------------------
--Connective Types
-------------------------------------------------------------------------------

type EK = (Bool,(Bool,(String,Bool)))

data JOIK = JOI (Bool,(String,Bool))
          | INT (Bool,(String,Bool))
          | INTGAhO (String,((Bool,(String,Bool)),String))
          deriving (Show,Eq)

type JOIK_JEK = Either JOIK EK
type JOIK_EK = Either JOIK EK

--Simple tree where each Node is a Connector and Leafs are things to be connected
data ConnectorTree c e = CTNode c (ConnectorTree c e,ConnectorTree c e)
                       | CTLeaf e
                       deriving (Show,Eq,Functor,Foldable)

ctLeaf :: SynIso a (ConnectorTree c a)
ctLeaf = Iso f g where
    f a = pure $ CTLeaf a
    g (CTLeaf a) = pure a
    g _ = lift $ Left "Not a CTLeaf."

type JJCTTS = ConnectorTree JOIK_JEK (Tagged SelbriNA)

--Con possible contains a Logical Connective and one based on a predicate
type Con = (Maybe JOIK_EK,Maybe JJCTTS)

--Bridia Tail containing a Selbri and tailing Sumti
type BT = (SelbriNA,[Sumti])

type BTCT = ConnectorTree Con BT

